package com.base.core.codec;

import cn.hutool.core.codec.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.util.Random;

public class TripleDesUtils {
    public static String encrypt(String source, String key) {
        try {
            SecretKey secretKey = new SecretKeySpec(build3DesKey(key), "DESede");
            Cipher cipher = Cipher.getInstance("DESede");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return Base64.encode(cipher.doFinal(source.getBytes()));
        } catch (java.security.NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException ex) {
            ex.printStackTrace();
        } catch (java.lang.Exception ex) {
            //ex.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String source, String key) {
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(key),"DESede");
            Cipher cipher = Cipher.getInstance("DESede");
            cipher.init(Cipher.DECRYPT_MODE, deskey);
            return new String(cipher.doFinal(Base64.decode(source)));
        } catch (java.security.NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException ex) {
            ex.printStackTrace();
        } catch (java.lang.Exception ex) {
            //ex.printStackTrace();
        }
        return null;
    }

    private static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24];
        byte[] temp = keyStr.getBytes("UTF-8");
        if (key.length > temp.length) {
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            System.arraycopy(temp, 0, key, 0, key.length);
        }
        return key;
    }

    public static String generate(int length) {
        Random rnd = new Random(System.currentTimeMillis());
        int letterLength = length - 1;
        byte[] buf = new byte[letterLength];
        for (int i = 0; i < letterLength; ++i) {
            int idx = Math.abs(rnd.nextInt()) % 13;
            int offset = idx % 2 == 1 ? 58 : 74;
            int ch = offset + idx;
            buf[i] = (byte) ch;
        }
        String clearText = insertRandomNumber(buf);
        return clearText;
    }

    private static String insertRandomNumber(byte[] buf) {
        StringBuffer sb = new StringBuffer(new String(buf));
        Random rnd = new Random(System.currentTimeMillis());
        int number = Math.abs(rnd.nextInt()) % 9;
        int offset = Math.abs(rnd.nextInt()) % (sb.length());
        sb.insert(offset, number);
        return sb.toString();
    }

}
